package edu.tgc.service.system;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import org.abyss.common.annotation.Log;
import org.abyss.common.exception.UpdateFaildServiceException;
import org.abyss.common.service.CommonCrudService;
import org.abyss.dictionary.service.DictionaryEasyUiService;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import edu.tgc.custom.EasyuiTree;
import edu.tgc.entity.hrm.IdCade;
import edu.tgc.entity.hrm.dictionary.HrmEducationType;
import edu.tgc.entity.hrm.dictionary.HrmEmployeeStatus;
import edu.tgc.entity.system.SysDept;
import edu.tgc.entity.system.SysDeptPosition;
import edu.tgc.entity.system.SysRole;
import edu.tgc.entity.system.SysUser;
import edu.tgc.repository.hrm.HrmEducationTypeRepository;
import edu.tgc.repository.hrm.HrmEmployeeStatusRepository;
import edu.tgc.repository.hrm.IdCadeRepository;
import edu.tgc.repository.system.SysDeptRepository;
import edu.tgc.repository.system.SysUserRepository;
import edu.tgc.service.hrm.IdCadeService;

@Log(value = "用户")
@Service
public class SysUserService extends CommonCrudService<SysUser, UUID> {

    @Autowired
    protected PasswordEncoder passwordEncoder;
    @Autowired
    protected SysDeptRepository sysDeptRepository;
    @Autowired
    protected SysPropertiesService sysPropertiesService;
    @Autowired
    protected SysRoleService sysRoleService;
    @Autowired
    protected SysUserRepository sysUserRepository;
    @Autowired
    protected IdCadeRepository cadeDAO;
    @Autowired
    protected HrmEmployeeStatusRepository employeeStatusDAO;
    @Autowired
    protected HrmEducationTypeRepository educationTypeDAO;
    /**
     * 向用户树里加入一个部门节点
     * 
     * @param nodes
     *            用户树
     * @param dept
     *            部门
     */
    public void addNode(List<EasyuiTree> nodes, SysDept dept) {
        EasyuiTree node = new EasyuiTree();
        node.setId(dept.getId());
        node.setIconCls("icon-dept");
        node.setState("closed");
        node.setText(dept.getName());
        node.setChildren(findTreeNodesByDeptId(dept.getId()));
        nodes.add(node);
    }

    /***
     * 向用户树里加入一个用户节点
     * 
     * @param nodes
     *            用户树
     * @param user
     *            用户
     */
    public void addNode(List<EasyuiTree> nodes, SysUser user) {
        EasyuiTree node = new EasyuiTree();
        node.setId(user.getId());
        node.setIconCls("icon-man");
        node.setState("open");
        node.setText(user.getCade().getName());
        nodes.add(node);
    }

    public SysUser clearPosition(UUID id) {
        SysUser entity = assertExists(id);
        try {
            entity.getDeptPositions().clear();
            entity = this.baseRepository.save(entity);
            this.baseRepository.flush();
            return entity;
        } catch (Throwable e) {
            throw new UpdateFaildServiceException("清除岗位失败", e);
        }
    }

    public SysUser findById(UUID id) {
        return this.sysUserRepository.findById(id);
    }

    public List<SysUser> findListByDeptId(UUID id) {
        return this.sysUserRepository.findByDeptId(id);
    }

    /***
     * 得到完整的用户树
     * 
     * @return 完整的用户树
     */
    public List<EasyuiTree> findTreeNodes() {
        SysDept root = this.sysDeptRepository.findByParentIsNull();
        return findTreeNodesByDeptId(root.getId());
    }

    /***
     * 得到下级用户树结点
     * 
     * @param id
     *            父节点
     * @return 下级用户树节点
     */
    public List<EasyuiTree> findTreeNodesByDeptId(UUID id) {
        List<EasyuiTree> nodes = new ArrayList<>();
        List<SysDept> depts = this.sysDeptRepository.findByParentId(id);
        for (SysDept dept : depts) {
        	if(dept.getEnabled()){
        		addNode(nodes, dept);
        	}
        }
        List<SysUser> users = this.sysUserRepository.findByDeptId(id);
        for (SysUser user : users) {
        	if(user.getDept()!=null&&user.getDept().getEnabled()&&user.getEnabled()){
        		addNode(nodes, user);
        	}
        }
        return nodes;
    }

    public Set<GrantedAuthority> getAuthorities(String username) {
        SysUser sysUser = getByUsername(username);
        return getAuthorities(sysUser);
    }

    public Set<GrantedAuthority> getAuthorities(SysUser sysUser) {
        Set<GrantedAuthority> authorities = new HashSet<>();
        if (sysUser != null && !CollectionUtils.isEmpty(sysUser.getRoles())) {
            for (SysRole sysRole : sysUser.getRoles()) {
                if (sysRole.getEnabled()) {
                    authorities.addAll(this.sysRoleService.getAuthorities(sysRole));
                }
            }
        }
        return authorities;
    }

    public Set<GrantedAuthority> getAuthorities(UUID id) {
        SysUser sysUser = assertExists(id);
        return getAuthorities(sysUser);
    }

    public SysUser getByUsername(String username) {
        return this.sysUserRepository.findByUsername(username);
    }

    @Override
    protected void preCreate(SysUser model, SysUser saveEntity) {
        // String password = StringUtils.hasText(model.getPassword()) ? model.getPassword() : sysPropertiesService.getDefaultPassword();
        String password = this.sysPropertiesService.getDefaultPassword();
        saveEntity.setPassword(this.passwordEncoder.encode(password));
    }

    public SysUser setPassword(UUID id, String password) {
        SysUser entity = assertExists(id);
        try {
            if (password == null) {
                password = this.sysPropertiesService.getDefaultPassword();
            }
            entity.setPassword(this.passwordEncoder.encode(password));
            entity = this.baseRepository.save(entity);
            this.baseRepository.flush();
            return entity;
        } catch (Throwable e) {
            throw new UpdateFaildServiceException("密码修改失败", e);
        }
    }

    public SysUser setPassword(UUID id, String oldPassword, String password) {
        SysUser entity = assertExists(id);
        if (this.passwordEncoder.matches(oldPassword, entity.getPassword())) {
            try {
                entity.setPassword(this.passwordEncoder.encode(password));
                entity = this.baseRepository.save(entity);
                this.baseRepository.flush();
                return entity;
            } catch (Throwable e) {
                throw new UpdateFaildServiceException("密码修改失败", e);
            }
        } else {
            throw new UpdateFaildServiceException("旧密码错误");
        }

    }

    public SysUser setPosition(UUID id, Set<SysDeptPosition> deptPositions) {
        SysUser entity = assertExists(id);
        try {
            entity.setDeptPositions(deptPositions);
            entity = this.baseRepository.save(entity);
            this.baseRepository.flush();
            return entity;
        } catch (Throwable e) {
            throw new UpdateFaildServiceException("设置岗位失败", e);
        }
    }

    public void setRoles(UUID id, Set<String> roleIds) {
        SysUser entity = this.baseRepository.findOne(id);
        HashSet<SysRole> roles = new HashSet<>();
        if (roleIds != null) {
            for (String roleId : roleIds) {
                roles.add(new SysRole(UUID.fromString(roleId)));
            }
        }
        entity.setRoles(roles);
        this.baseRepository.saveAndFlush(entity);
    }
    
    @Transactional
	public String importHrm(HSSFWorkbook wb) {
    	String errorStr="";
		List<SysUser> sysUsers=new ArrayList<>();
		List<IdCade> idCades=new ArrayList<>();
		Sheet sheet=wb.getSheetAt(0);
		int lastRowNum = sheet.getLastRowNum();
		for(int i=1;i<=lastRowNum;i++){
			Row row=sheet.getRow(i);
			IdCade cade=new IdCade();
			Cell cell=row.getCell(0);
			String name = cell.getStringCellValue().trim();
			cade.setName(name);
			cell=row.getCell(1);
			String idNo=cell.getStringCellValue().trim();
			cade.setIdNo(idNo);
			IdCade cade1=cadeDAO.findByIdNo(idNo);
			if(cade1!=null){
				errorStr+="第"+(i+1)+"行，身份证号重复。";
				break;
			}
			cell=row.getCell(3);
			String sex=cell.getStringCellValue().trim();
			cade.setSex(sex);
			
			/*cell=row.getCell(3);
			String username=cell.getStringCellValue().trim();
			cade.setNation(nation);*/

			cell=row.getCell(4);
			String nation=cell.getStringCellValue().trim();
			cade.setNation(nation);
			cell=row.getCell(5);
			Date born = cell.getDateCellValue();
			cade.setBorn(born);
			cell=row.getCell(6);
			String address=cell.getStringCellValue().trim();
			cade.setAddress(address);
			cell=row.getCell(7);
			Date lifeTimeB=cell.getDateCellValue();
			cade.setUserLifeB(lifeTimeB);
			cell=row.getCell(8);
			Date lifeTimeE=cell.getDateCellValue();
			cade.setUserLifeE(lifeTimeE);
			cell=row.getCell(9);
			String police = cell.getStringCellValue().trim();
			cade.setPolice(police);
			//idCades.add(cade);
			//cadeDAO.save(cade);
			SysUser user=new SysUser();
			//user.setCade(cade);
			cell=row.getCell(2);
			String username=getStringCellValue(cell).trim();
			if(!StringUtils.hasText(username)){
				errorStr+="第"+(i+1)+"行，用户名为空。";
				break;
			}
			SysUser user2=sysUserRepository.findByUsername(username);
			if(user2!=null){
				errorStr+="第"+(i+1)+"行，用户名重复。";
				break;
			}else{
				user.setUsername(username);
			}
			cell=row.getCell(10);
			String deptName=cell.getStringCellValue().trim();
			SysDept dept=sysDeptRepository.findByName(deptName);
			if(dept==null){
				errorStr+="第"+(i+1)+"行，部门名称错误。";
				break;
			}else{
				user.setDept(dept);
			}
			cell=row.getCell(11);
			String statusName=cell.getStringCellValue().trim();
			HrmEmployeeStatus status= employeeStatusDAO.findByName(statusName);
			if(status!=null){
				user.setStatus(status);
			}else{
				errorStr+="第"+(i+1)+"行，人员种类错误。";
				break;
				
			}
			cell=row.getCell(12);
			String phone=getStringCellValue(cell).trim();
			user.setTelphone(phone);
			cell=row.getCell(13);
			String qq=getStringCellValue(cell).trim();
			user.setQq(qq);
			cell=row.getCell(14);
			String email=getStringCellValue(cell).trim();
			user.setEmail(email);
			cell=row.getCell(15);
			String educationName=getStringCellValue(cell).trim();
			HrmEducationType education=educationTypeDAO.findByName(educationName);
			if(education==null){
				errorStr+="第"+(i+1)+"行，学历错误。";
				break;
			}else{
				user.setEducation(education);
			}
			cell=row.getCell(16);
			String major=getStringCellValue(cell).trim();
			user.setMajor(major);
			user.setPassword(passwordEncoder.encode("abcABC123"));
			idCades.add(cade);
			sysUsers.add(user);
		}
		Date now=new Date();
		for(int i=0;i<sysUsers.size();i++){
			SysUser user=sysUsers.get(i);
			IdCade cade=idCades.get(i);
			cade.setIsUsed(true);
			cadeDAO.saveAndFlush(cade);
			user.setCade(cade);
			user.setCreateTime(now);
			user.setLastModifyTime(now);
			sysUserRepository.save(user);
		}
		return errorStr;
	}
    /**
     * 获取单元格数据内容为字符串类型的数据
     * 
     * @param cell Excel单元格
     * @return String 单元格数据内容
     */
    private String getStringCellValue(Cell cell) {
        String strCell = "";
        switch (cell.getCellType()) {
        case HSSFCell.CELL_TYPE_STRING:
            strCell = cell.getStringCellValue();
            break;
        case HSSFCell.CELL_TYPE_NUMERIC:
            strCell = String.valueOf(cell.getNumericCellValue());
            break;
        case HSSFCell.CELL_TYPE_BOOLEAN:
            strCell = String.valueOf(cell.getBooleanCellValue());
            break;
        case HSSFCell.CELL_TYPE_BLANK:
            strCell = "";
            break;
        default:
            strCell = "";
            break;
        }
        if (strCell.equals("") || strCell == null) {
            return "";
        }
        return strCell;
    }
    
    /**
     * 获取单元格数据内容为日期类型的数据
     * 
     * @param cell
     *            Excel单元格
     * @return String 单元格数据内容
     */
    private String getDateCellValue(HSSFCell cell) {
        String result = "";
        try {
            int cellType = cell.getCellType();
            if (cellType == HSSFCell.CELL_TYPE_NUMERIC) {
                Date date = cell.getDateCellValue();
                result = (date.getYear() + 1900) + "-" + (date.getMonth() + 1)
                        + "-" + date.getDate();
            } else if (cellType == HSSFCell.CELL_TYPE_STRING) {
                String date = getStringCellValue(cell);
                result = date.replaceAll("[年月]", "-").replace("日", "").trim();
            } else if (cellType == HSSFCell.CELL_TYPE_BLANK) {
                result = "";
            }
        } catch (Exception e) {
            System.out.println("日期格式不正确!");
            e.printStackTrace();
        }
        return result;
    }

}
